// --------------------------------------------------------------------------------------------
// Version: MPL 1.1/GPL 2.0/LGPL 2.1
// 
// The contents of this file are subject to the Mozilla Public License Version
// 1.1 (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
// 
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
// 
// <remarks>
// Generated by IDLImporter from file nsIThreadInternal.idl
// 
// You should use these interfaces when you access the COM objects defined in the mentioned
// IDL/IDH file.
// </remarks>
// --------------------------------------------------------------------------------------------
namespace Gecko
{
	using System;
	using System.Runtime.InteropServices;
	using System.Runtime.InteropServices.ComTypes;
	using System.Runtime.CompilerServices;
	
	
	/// <summary>
    /// The XPCOM thread object implements this interface, which allows a consumer
    /// to observe dispatch activity on the thread.
    /// </summary>
	[ComImport()]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("9cc51754-2eb3-4b46-ae99-38a61881c622")]
	public interface nsIThreadInternal : nsIThread
	{
		
		/// <summary>
        /// Check to see if this event target is associated with the current thread.
        ///
        /// @returns
        /// A boolean value that if "true" indicates that events dispatched to this
        /// event target will run on the current thread (i.e., the thread calling
        /// this method).
        /// </summary>
		[return: MarshalAs(UnmanagedType.U1)]
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		new bool IsOnCurrentThread();
		
		/// <summary>
        /// Dispatch an event to this event target.  This function may be called from
        /// any thread, and it may be called re-entrantly.
        ///
        /// @param event
        /// The alreadyAddRefed<> event to dispatch.
        /// NOTE that the event will be leaked if it fails to dispatch. Also note
        /// that if "flags" includes DISPATCH_SYNC, it may return error from Run()
        /// after a successful dispatch. In that case, the event is not leaked.
        /// @param flags
        /// The flags modifying event dispatch.  The flags are described in detail
        /// below.
        ///
        /// @throws NS_ERROR_INVALID_ARG
        /// Indicates that event is null.
        /// @throws NS_ERROR_UNEXPECTED
        /// Indicates that the thread is shutting down and has finished processing
        /// events, so this event would never run and has not been dispatched.
        /// </summary>
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		new void DispatchFromC(System.IntPtr @event, uint flags);
		
		/// <summary>
        /// Version of Dispatch to expose to JS, which doesn't require an alreadyAddRefed<>
        /// (it will be converted to that internally)
        ///
        /// @param event
        /// The (raw) event to dispatch.
        /// @param flags
        /// The flags modifying event dispatch.  The flags are described in detail
        /// below.
        ///
        /// @throws NS_ERROR_INVALID_ARG
        /// Indicates that event is null.
        /// @throws NS_ERROR_UNEXPECTED
        /// Indicates that the thread is shutting down and has finished processing
        /// events, so this event would never run and has not been dispatched.
        /// </summary>
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		new void Dispatch([MarshalAs(UnmanagedType.Interface)] nsIRunnable @event, uint flags);
		
		/// <summary>
        /// @returns
        /// The NSPR thread object corresponding to this nsIThread.
        /// </summary>
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		new System.IntPtr GetPRThreadAttribute();
		
		/// <summary>
        /// Shutdown the thread.  This method prevents further dispatch of events to
        /// the thread, and it causes any pending events to run to completion before
        /// the thread joins (see PR_JoinThread) with the current thread.  During this
        /// method call, events for the current thread may be processed.
        ///
        /// This method MAY NOT be executed from the thread itself.  Instead, it is
        /// meant to be executed from another thread (usually the thread that created
        /// this thread or the main application thread).  When this function returns,
        /// the thread will be shutdown, and it will no longer be possible to dispatch
        /// events to the thread.
        ///
        /// @throws NS_ERROR_UNEXPECTED
        /// Indicates that this method was erroneously called when this thread was
        /// the current thread, that this thread was not created with a call to
        /// nsIThreadManager::NewThread, or if this method was called more than once
        /// on the thread object.
        /// </summary>
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		new void Shutdown();
		
		/// <summary>
        /// This method may be called to determine if there are any events ready to be
        /// processed.  It may only be called when this thread is the current thread.
        ///
        /// Because events may be added to this thread by another thread, a "false"
        /// result does not mean that this thread has no pending events.  It only
        /// means that there were no pending events when this method was called.
        ///
        /// @returns
        /// A boolean value that if "true" indicates that this thread has one or
        /// more pending events.
        ///
        /// @throws NS_ERROR_UNEXPECTED
        /// Indicates that this method was erroneously called when this thread was
        /// not the current thread.
        /// </summary>
		[return: MarshalAs(UnmanagedType.U1)]
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		new bool HasPendingEvents();
		
		/// <summary>
        /// Process the next event.  If there are no pending events, then this method
        /// may wait -- depending on the value of the mayWait parameter -- until an
        /// event is dispatched to this thread.  This method is re-entrant but may
        /// only be called if this thread is the current thread.
        ///
        /// @param mayWait
        /// A boolean parameter that if "true" indicates that the method may block
        /// the calling thread to wait for a pending event.
        ///
        /// @returns
        /// A boolean value that if "true" indicates that an event was processed.
        ///
        /// @throws NS_ERROR_UNEXPECTED
        /// Indicates that this method was erroneously called when this thread was
        /// not the current thread.
        /// </summary>
		[return: MarshalAs(UnmanagedType.U1)]
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		new bool ProcessNextEvent([MarshalAs(UnmanagedType.U1)] bool mayWait);
		
		/// <summary>
        /// Shutdown the thread asynchronously.  This method immediately prevents
        /// further dispatch of events to the thread, and it causes any pending events
        /// to run to completion before this thread joins with the current thread.
        ///
        /// UNLIKE shutdown() this does not process events on the current thread.
        /// Instead it merely ensures that the current thread continues running until
        /// this thread has shut down.
        ///
        /// This method MAY NOT be executed from the thread itself.  Instead, it is
        /// meant to be executed from another thread (usually the thread that created
        /// this thread or the main application thread).  When this function returns,
        /// the thread will continue running until it exhausts its event queue.
        ///
        /// @throws NS_ERROR_UNEXPECTED
        /// Indicates that this method was erroneously called when this thread was
        /// the current thread, that this thread was not created with a call to
        /// nsIThreadManager::NewThread, or if this method was called more than once
        /// on the thread object.
        /// </summary>
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		new void AsyncShutdown();
		
		/// <summary>
        /// Get/set the current thread observer (may be null).  This attribute may be
        /// read from any thread, but must only be set on the thread corresponding to
        /// this thread object.  The observer will be released on the thread
        /// corresponding to this thread object after all other events have been
        /// processed during a call to Shutdown.
        /// </summary>
		[return: MarshalAs(UnmanagedType.Interface)]
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		nsIThreadObserver GetObserverAttribute();
		
		/// <summary>
        /// Get/set the current thread observer (may be null).  This attribute may be
        /// read from any thread, but must only be set on the thread corresponding to
        /// this thread object.  The observer will be released on the thread
        /// corresponding to this thread object after all other events have been
        /// processed during a call to Shutdown.
        /// </summary>
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		void SetObserverAttribute([MarshalAs(UnmanagedType.Interface)] nsIThreadObserver aObserver);
		
		/// <summary>
        /// Add an observer that will *only* receive onProcessNextEvent,
        /// beforeProcessNextEvent. and afterProcessNextEvent callbacks. Always called
        /// on the target thread, and the implementation does not have to be
        /// threadsafe. Order of callbacks is not guaranteed (i.e.
        /// afterProcessNextEvent may be called first depending on whether or not the
        /// observer is added in a nested loop). Holds a strong ref.
        /// </summary>
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		void AddObserver([MarshalAs(UnmanagedType.Interface)] nsIThreadObserver observer);
		
		/// <summary>
        /// Remove an observer added via the addObserver call. Once removed the
        /// observer will never be called again by the thread.
        /// </summary>
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		void RemoveObserver([MarshalAs(UnmanagedType.Interface)] nsIThreadObserver observer);
		
		/// <summary>
        /// This method causes any events currently enqueued on the thread to be
        /// suppressed until PopEventQueue is called, and any event dispatched to this
        /// thread's nsIEventTarget will queue as well. Calls to PushEventQueue may be
        /// nested and must each be paired with a call to PopEventQueue in order to
        /// restore the original state of the thread. The returned nsIEventTarget may
        /// be used to push events onto the nested queue. Dispatching will be disabled
        /// once the event queue is popped. The thread will only ever process pending
        /// events for the innermost event queue. Must only be called on the target
        /// thread.
        /// </summary>
		[return: MarshalAs(UnmanagedType.Interface)]
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		nsIEventTarget PushEventQueue();
		
		/// <summary>
        /// Revert a call to PushEventQueue. When an event queue is popped, any events
        /// remaining in the queue are appended to the elder queue. This also causes
        /// the nsIEventTarget returned from PushEventQueue to stop dispatching events.
        /// Must only be called on the target thread, and with the innermost event
        /// queue.
        /// </summary>
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		void PopEventQueue([MarshalAs(UnmanagedType.Interface)] nsIEventTarget aInnermostTarget);
	}
	
	/// <summary>
    /// This interface provides the observer with hooks to implement a layered
    /// event queue.  For example, it is possible to overlay processing events
    /// for a GUI toolkit on top of the events for a thread:
    ///
    /// var NativeQueue;
    /// Observer = {
    /// onDispatchedEvent(thread) {
    /// NativeQueue.signal();
    /// }
    /// onProcessNextEvent(thread, mayWait) {
    /// if (NativeQueue.hasNextEvent())
    /// NativeQueue.processNextEvent();
    /// while (mayWait && !thread.hasPendingEvent()) {
    /// NativeQueue.wait();
    /// NativeQueue.processNextEvent();
    /// }
    /// }
    /// };
    ///
    /// NOTE: The implementation of this interface must be threadsafe.
    ///
    /// NOTE: It is valid to change the thread's observer during a call to an
    /// observer method.
    ///
    /// NOTE: Will be split into two interfaces soon: one for onProcessNextEvent and
    /// afterProcessNextEvent, then another that inherits the first and adds
    /// onDispatchedEvent.
    /// </summary>
	[ComImport()]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("cc8da053-1776-44c2-9199-b5a629d0a19d")]
	public interface nsIThreadObserver
	{
		
		/// <summary>
        /// This method is called after an event has been dispatched to the thread.
        /// This method may be called from any thread.
        ///
        /// @param thread
        /// The thread where the event is being dispatched.
        /// </summary>
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		void OnDispatchedEvent([MarshalAs(UnmanagedType.Interface)] nsIThreadInternal thread);
		
		/// <summary>
        /// This method is called when nsIThread::ProcessNextEvent is called.  It does
        /// not guarantee that an event is actually going to be processed.  This method
        /// is only called on the target thread.
        ///
        /// @param thread
        /// The thread being asked to process another event.
        /// @param mayWait
        /// Indicates whether or not the method is allowed to block the calling
        /// thread.  For example, this parameter is false during thread shutdown.
        /// </summary>
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		void OnProcessNextEvent([MarshalAs(UnmanagedType.Interface)] nsIThreadInternal thread, [MarshalAs(UnmanagedType.U1)] bool mayWait);
		
		/// <summary>
        /// This method is called (from nsIThread::ProcessNextEvent) after an event
        /// is processed.  It does not guarantee that an event was actually processed
        /// (depends on the value of |eventWasProcessed|.  This method is only called
        /// on the target thread.  DO NOT EVER RUN SCRIPT FROM THIS CALLBACK!!!
        ///
        /// @param thread
        /// The thread that processed another event.
        /// @param eventWasProcessed
        /// Indicates whether an event was actually processed. May be false if the
        /// |mayWait| flag was false when calling nsIThread::ProcessNextEvent().
        /// </summary>
		[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
		void AfterProcessNextEvent([MarshalAs(UnmanagedType.Interface)] nsIThreadInternal thread, [MarshalAs(UnmanagedType.U1)] bool eventWasProcessed);
	}
}
